#ifndef BLOCKWISE_INTEGRATED_LOCATION_HPP
#define BLOCKWISE_INTEGRATED_LOCATION_HPP

#include "typeAliases.hpp"
#include "reconstruction.hpp"

namespace hms::swe
{

enum class BlockLocation {
	inner,
	bottom,
	top,
	left,
	right,
	bottomLeft,
	bottomRight,
	topLeft,
	topRight,
};

template<BlockLocation loc>
constexpr bool atBottom(){
	using B = BlockLocation;
	return
		   loc == B::bottom
		|| loc == B::bottomLeft
		|| loc == B::bottomRight;
}

template<BlockLocation loc>
constexpr bool atTop(){
	using B = BlockLocation;
	return
		   loc == B::top
		|| loc == B::topLeft
		|| loc == B::topRight;
}

template<BlockLocation loc>
constexpr bool atLeft(){
	using B = BlockLocation;
	return
		   loc == B::left
		|| loc == B::bottomLeft
		|| loc == B::topLeft;
}

template<BlockLocation loc>
constexpr bool atRight(){
	using B = BlockLocation;
	return
		   loc == B::right
		|| loc == B::bottomRight
		|| loc == B::topRight;
}

template<BlockLocation loc>
constexpr bool atMiddleCols(){
	using B = BlockLocation;
	return
		   loc == B::bottom
		|| loc == B::inner
		|| loc == B::top;
}

template<BlockLocation loc>
constexpr bool atMiddleRows(){
	using B = BlockLocation;
	return
		   loc == B::left
		|| loc == B::inner
		|| loc == B::right;
}

template<BlockLocation loc>
constexpr Index addBottom(){
	if constexpr ( atBottom<loc>() ){
		return 1;
	} else {
		return 2;
	}
}

template<BlockLocation loc>
constexpr Index addTop(){
	if constexpr ( atTop<loc>() ){
		return 1;
	} else {
		return 2;
	}
}

template<BlockLocation loc>
constexpr Index addLeft(){
	if constexpr ( atLeft<loc>() ){
		return 1;
	} else {
		return 2;
	}
}

template<BlockLocation loc>
constexpr Index addRight(){
	if constexpr ( atRight<loc>() ){
		return 1;
	} else {
		return 2;
	}
}

template<BlockLocation loc, EdgeRange orien>
constexpr ReconstructionType recType(){
	using RT = ReconstructionType;
	if constexpr ( orien == EdgeRange::horizontal ){
		return atMiddleRows<loc>() ? RT::secondOrder : RT::central;
	} else { // vertical
		return atMiddleCols<loc>() ? RT::secondOrder : RT::central;
	}
}

} // namespace hms::swe

#endif